home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / scrasm / init.inc < prev    next >
Encoding:
Text File  |  1993-03-09  |  14.9 KB  |  375 lines

  1. ;; Error messages
  2. ERR_OK          EQU     0
  3. msgErr0         db      'Later!',13,10,'$'
  4. ERR_MEM         EQU     1
  5. msgErr1         db      'Error 001:  Out of memory?',13,10,'$'
  6. ERR_CPU         EQU     2
  7. msgErr2         db      'Error 002:  CPU must be at least an 80386.',13,10,'$'
  8. ERR_FILE        EQU     3
  9. msgErr3         db      'Error 003:  File error.',13,10,'$'
  10. ERR_FILENOTFOUND EQU    4
  11. msgErr4         db      'Error 004:  File not found.',13,10,'$'
  12. msgtblError     dw      offset msgErr0, offset msgErr1, offset msgErr2,
  13.                         offset msgErr3, offset msgErr4
  14. nError          db      0
  15.  
  16. ;; CPU name strings
  17. CPUName86       DB      "8088/8086$"
  18. CPUName286      DB      "80286DX/SX$"
  19. CPUName386      DB      "80386DX/SX$"
  20. CPUName486      DB      "80486DX/SX or better$"
  21. CPUNameTable    DW      CPUName86,CPUName286,CPUName386,CPUName486
  22.  
  23. EVEN
  24. msgCPUTypeIs    DB      "Your CPU type:  $"
  25. EVEN
  26. msgCPUTypeIsEnd DB      13,10,'$'
  27. nCPU            DB      0
  28.  
  29. EVEN
  30. msgPages        DB      'Pages displayed:  '
  31. strNumPages     DB      6 dup (?),13,10,'$'
  32.  
  33. EVEN
  34. bufText         DW      80*50 DUP (?)   ; Needs this much to hold
  35.                                         ; a 50-line screen...
  36. wCPos           DW      0
  37. nDisplay        DB      0
  38.  
  39. EVEN
  40. fnMap1          db      'DIAGONAL.MAP',0
  41. fnTiles1        db      'DIAGONAL.TIL',0
  42. fnPalette       db      'DIAGONAL.PAL',0        ; only one allowed, for now
  43. fnMap2          db      'SCROLL.MAP',0
  44. fnTiles2        db      'SCROLL.TIL',0
  45.  
  46. fntblMap        dw      offset fnMap1,offset fnMap2
  47. fntblTiles      dw      offset fnTiles1,offset fnTiles2
  48. nMap            dw      0
  49.  
  50. ;; CPUType routine snatched from Ray Duncan's _Power Programming MASM_
  51. ;; chapter 14.  Reformatted to my style, but I left the code alone
  52. ;; except that it used to push a bunch of stuff, but doesn't any more
  53. ;; because I don't care what gets destroyed.
  54. CPUType         PROC    near
  55.                 pushf                   ; now try to clear bits 12-15
  56.                 pop     ax              ; of CPU flags
  57.                 and     ax,0fffh
  58.                 push    ax              ; set modified CPU flags
  59.                 popf
  60.                 pushf
  61.                 pop     ax              ; get flags again
  62.                 and     ax,0f000h       ; if bits 12-15 are still
  63.                 cmp     ax,0f000h       ; set, this is 8086/88
  64.                 jne     cpu1            ; jump, not 8086/88
  65.                 mov     nCPU,CPU8086    ; set nCPU = 86/88 CPU type
  66.                 jmp     cpux            ; and exit
  67.  
  68. cpu1:           or      ax,0f000h       ; must be 286 or later,
  69.                 push    ax              ; now try to set bits 12-15
  70.                 popf                    ; of CPU flags
  71.                 pushf
  72.                 pop     ax              ; if bits 12-15 can't be
  73.                 and     ax,0f000h       ; set, this is a 286
  74.                 jnz     cpu2            ; jump, not 80286
  75.                 mov     nCPU,CPU80286   ; set nCPU = 286 CPU type
  76.                 jmp     cpux            ; and exit
  77.  
  78. cpu2:           mov     bx,sp           ; 386 or later, save SP
  79.                 and     sp,not 3        ; avoid stack alignment fault
  80.                 pushfd                  ; get value of EFLAGS
  81.                 pop     eax
  82.                 mov     ecx,eax         ; save copy of EFLAGS
  83.                 xor     eax,40000h      ; flip AC bit in EFLAGS
  84.                 push    eax             ; try and force EFLAGS
  85.                 popfd
  86.                 pushfd                  ; get back EFLAGS value
  87.                 pop     eax
  88.                 mov     sp,bx           ; restore old stack pointer
  89.                 xor     eax,ecx         ; can AC bit be changed?
  90.                 jnz     cpu3            ; no, jump, not a 386
  91.                 mov     nCPU,CPU80386   ; set nCPU = 386 CPU type
  92.                 jmp     cpux            ; and exit
  93.  
  94. cpu3:           mov     nCPU,CPU80486   ; set nCPU = 486 CPU type
  95.  
  96. cpux:           mov     bl,nCPU
  97.                 xor     bh,bh
  98.                 shl     bx,1
  99.                 DOSPRINT <offset msgCPUTypeIs>
  100.                 DOSPRINT CPUNameTable[bx]
  101.                 DOSPRINT <offset msgCPUTypeIsEnd>
  102.                 ret                     ; return with nCPU = CPU type
  103. CPUType         ENDP
  104.  
  105. ;; Initialize:  So far, all it does is make sure you have a 386 +
  106. ;; (because that's what I assembled the code for).
  107. Initialize      PROC    near
  108.         ; Set DS = CS in this program, since data is local
  109.                 mov     ax,cs
  110.                 mov     segCode,ax      ; Store the Code Segment
  111.                 mov     bx,ds
  112.                 mov     segPSP,bx       ; Store the PSP Segment
  113.                 mov     ds,ax           ; Set DS = CS
  114.  
  115.         ; Resize code to 64K
  116.         CODE_SIZE EQU 64                ; <- this is arbitrary.
  117.                 ; ES already -> allocated segment
  118.                 mov     ah,4ah
  119.                 mov     bx,64*CODE_SIZE
  120.                 int     21h
  121.                 mov     nError,ERR_MEM
  122.                 jc      TerminateError
  123.  
  124. ;; I've chosen not to implement sprites yet so that I can get this out
  125. ;; the door...
  126. ;; ; 320x200 buffer for sprite drawing.  To draw sprites, first draw them
  127. ;; ; into this buffer, adding rectangles to the current rectangle list.
  128. ;; ; Then, use BUFFER_COPY to put out the buffers with the current
  129. ;; ; rectangle list to the screen.  BUFFER_COPY will ensure minimal VGA
  130. ;; ; writing.
  131. ;;         ; Create a buffer segment
  132. ;;                 mov     bx,(320 * 200) / 16
  133. ;;                 mov     ah,48h
  134. ;;                 int     21h
  135. ;;                 mov     nError,ERR_MEM
  136. ;;                 jc      TerminateError
  137. ;;                 mov     segBuffer,ax
  138.  
  139.                 call    CPUType
  140.                 mov     nError,ERR_CPU
  141.                 cmp     nCPU,2
  142.                 jl      TerminateError
  143.  
  144.                 mov     ds,segCode
  145.                 mov     dx,offset fnPalette
  146.                 call    LoadPaletteFile
  147.                 jc      TerminateError
  148.  
  149.                 call    LoadIndex
  150.                 jc      TerminateError
  151.  
  152.                 KEYB_START
  153.  
  154.                 call    Beginning       ; Can display an entry screen here
  155.  
  156.         ; This is linked in from Michael Abrash's zen timer code.
  157.         ; (But I wrote the Click myself)
  158.         call    Click
  159.         call    ZTimerOn
  160.  
  161.                 call    MainLoop
  162.  
  163.         call    ZTimerOff
  164.         call    Click
  165.  
  166.                 call    Ending          ; Can display an exit screen here
  167.  
  168.                 KEYB_END
  169.  
  170. Terminate:      mov     nError,ERR_OK
  171. TerminateError:
  172.                 mov     ax,cs   ;DOS functions require that DS point
  173.                 mov     ds,ax   ; to text to be displayed on the screen
  174.                 mov     bh,0
  175.                 mov     bl,nError
  176.                 shl     bx,1
  177.                 DOSPRINT msgtblError[bx]
  178.  
  179.                 mov     ax,pages
  180.                 mov     ds,segCode
  181.                 mov     si,offset strNumPages
  182.                 call    Int2Ascii
  183.                 DOSPRINT <offset msgPages>
  184.  
  185.         call    ZTimerReport
  186.  
  187.                 mov     al,nError
  188.                 mov     ah,4ch        ; DOS Terminate
  189.                 int     21h
  190.                 ; Don't need to RET!  We're outta here
  191. Initialize      ENDP
  192.  
  193. ;; Clicks the internal speaker.  I use this to indicate that page timing
  194. ;; has started.
  195. Click           PROC
  196.                 in      al,61h
  197.                 mov     ah,al
  198.                 or      al,3
  199.                 out     61h,al
  200.  
  201.                 mov     cx,5000         ; (this is an arbitrary delay!)
  202. spkr_on:        loop    spkr_on
  203.                 mov     al,ah
  204.                 out     61h,al
  205.                 ret
  206. Click           ENDP
  207.  
  208. ;; Copied from an old 8088 "Learn Assembly" book and changed a bit
  209. Int2Ascii       PROC
  210.                 mov     cx,6
  211.                 mov     byte ptr cs:[si],' '
  212.                 mov     byte ptr cs:[si+1],'0'
  213.                 mov     byte ptr cs:[si+2],'0'
  214.                 mov     byte ptr cs:[si+3],'0'
  215.                 mov     byte ptr cs:[si+4],'0'
  216.                 mov     byte ptr cs:[si+5],'0'
  217.                 add     si,6
  218.                 mov     cx,10
  219.                 or      ax,ax
  220.                 jns     clear_divide
  221.                 neg     ax
  222.                 mov     byte ptr cs:[si-6],'-'
  223. clear_divide:   mov     dx,0
  224.                 div     cx
  225.                 add     dx,'0'
  226.                 dec     si
  227.                 mov     cs:[si],dl
  228.                 or      ax,ax
  229.                 jnz     clear_divide
  230.                 ret
  231. Int2Ascii       ENDP
  232.  
  233. ;; Given a filename at DS:DX, reads the file into memory and returns
  234. ;; a pointer to it as DX:0000.
  235. ;; Note that this routine obviously will only work correctly for
  236. ;; a file < 640k in size, but you can bring in files bigger than 64k.
  237. ;; This code comes from Future Crew's STMIK sampler "Mental Surgery"
  238. ;; and I commented it up to make it fit in with my stuff a little better.
  239. ;; Thank you, FC, for releasing that code!  Several of the routines
  240. ;; in this program were inspired or helped along by having that source...
  241. ;; Most recently, added in error codes.
  242. EVEN
  243. LoadFile        PROC    NEAR
  244.                 ;set: DX=offset to filename
  245.                 ;return: DX=segment of file
  246.  
  247.         ; Open the datafile at DS:DX.
  248.                 mov     ax,3D00h        ; 3D,00 -> Open file, read only
  249.                                         ; DS:DX already points at filename
  250.                 int     21h             ;  returns AX=file handle
  251.                 mov     cl,ERR_FILENOTFOUND
  252.                 jc      ferror
  253.                 mov     bx,ax           ; Store file handle in BX
  254.                 mov     si,bx           ; and also in a variable
  255.  
  256.         ; Get the length of the file so we know how much to allocate
  257.                 mov     ax,4202h        ; 42,02 -> Seek, signed from end
  258.                 mov     cx,0            ; CX:DX is a long file offset,
  259.                                         ; BX is already set as file handle
  260.                 mov     dx,0            ;  zero in this case = end of file
  261.                 int     21h             ; (returns long offset in DX:AX)
  262.                 mov     cl,ERR_FILE
  263.                 jc      ferror
  264.  
  265. ;;;             shr     dx,1            ; This is original FC code,
  266. ;;;             rcr     ax,1            ; which I removed because the
  267. ;;;             shr     dx,1            ; 386 has a nice instruction
  268. ;;;             rcr     ax,1            ; to do this all!
  269. ;;;             shr     dx,1            ; But 286 users will want to
  270. ;;;             rcr     ax,1            ; return to this code, instead
  271. ;;;             shr     dx,1            ; of SHRD dx,ax,4
  272. ;;;             rcr     ax,1            ;
  273.  
  274.         ; Now turn that long DX:AX into a number of paragraphs to allocate
  275.         ; for when we read the file.
  276.                 shrd    ax,dx,4         ; Divides long DX:AX by 4,
  277.                 mov     bx,ax           ;  and stores this in BX
  278.                 inc     bx      ; HHMMMM?  One more needed for small #'s
  279.                 mov     ah,48h          ; 48 -> Allocate memory
  280.                                         ; BX already = # of paragraphs
  281.                 int     21h
  282.                 mov     cl,ERR_MEM
  283.                 jc      ferror
  284.                 mov     di,ax           ; store this in a variable
  285.  
  286.         ; Seek the file back to the beginning in order to read it into
  287.         ; the memory we just allocated.
  288.                 mov     ax,4200h        ; 42,00 -> Seek, absolute offset
  289.                 mov     bx,si           ; BX is the file handle.
  290.                 mov     cx,0            ; CX:DX is a long offset
  291.                 mov     dx,0
  292.                 int     21h
  293.                 jc      ferror
  294.  
  295.         ; Now read the file into memory
  296.                 mov     ds,di           ; DS points at alloc'd memory
  297. ReadBlock:      mov     ah,3fh          ; 3F -> Read file
  298.                 mov     cx,32768        ; read 32768 bytes at a time
  299.                 mov     dx,0            ; DS:DX points at beginning of
  300.                 int     21h             ;  this block of memory.
  301.                 mov     cl,ERR_FILE
  302.                 jc      ferror
  303.                 mov     dx,ds           ; Offset DS by (32768/16), which
  304.                 add     dx,800h         ;  is the number of paragraphs in
  305.                 mov     ds,dx           ;  each block of 32768 bytes.
  306.                 cmp     ax,32768        ; Did we actually read 32768 bytes?
  307.                 je      ReadBlock       ; If so, there's more to read...
  308.                                         ; Otherwise, we've read all the
  309.                                         ;  data in the file.
  310.  
  311.         ; So now, close the file handle.
  312.                 mov     ah,3Eh          ; 3E -> Close file
  313.                                         ; BX still is the file handle
  314.                 int     21h
  315.  
  316.         ; Everything went ok.  Return the segment in DX.
  317.                 mov     dx,di
  318.                 mov     nError,ERR_OK
  319.                 ret
  320. ferror:         mov     nError,cl
  321.                 ret
  322. LoadFile        ENDP
  323.  
  324. ;; Eventually, this should load in an index of all data files to
  325. ;; allow for filenames to be specified outside of the program.  The
  326. ;; goal is to make the program have no hardcoded filenames...
  327. ;; Of course, the structure of this index and its entries will be
  328. ;; hardcoded, as will the structures of all of the files it includes.
  329. LoadIndex       PROC    near
  330.                 ret
  331. LoadIndex       ENDP
  332.  
  333. ;; Save the current video mode and cursor position with standard
  334. ;; BIOS calls
  335. SaveVideo       PROC    near
  336.                 mov     ah,0Fh
  337.                 int     10h             ; Get current display Mode
  338.                 mov     nDisplay,al
  339.                 mov     ah,03h
  340.                 mov     bh,0
  341.                 int     10h
  342.                 mov     wCPos,dx
  343.  
  344.                 mov     ds,segText
  345.                 mov     si,0
  346.                 mov     es,segCode
  347.                 mov     di,offset bufText
  348.                 mov     cx,80*50
  349.             rep movsw
  350.                 ret
  351. SaveVideo       ENDP
  352.  
  353. ;; Restore the current video mode and cursor position with standard
  354. ;; BIOS calls
  355. RestoreVideo    PROC    near
  356.                 mov     ah,00h
  357.                 mov     al,nDisplay
  358.                 int     10h             ; Get current display Mode
  359.                 mov     ah,02h
  360.                 mov     bh,0
  361.                 mov     dx,wCPos
  362.                 int     10h
  363.  
  364.                 PAL_UPDATE      ; When flipping into text mode, re-do the
  365.                                 ; palette because the BIOS changes it.
  366.  
  367.                 mov     es,segText
  368.                 mov     di,0
  369.                 mov     ds,segCode
  370.                 mov     si,offset bufText
  371.                 mov     cx,80*50
  372.             rep movsw
  373.                 ret
  374. RestoreVideo    ENDP
  375.